#ifndef NNE_DEVICE_VECTOR_PATH_H_
#define NNE_DEVICE_VECTOR_PATH_H_

#include "type.h"
#include "util.h"
#include "mem/dram.h"
#include <memory>

class VectorPath{
public:
    VectorPath(std::shared_ptr<Dram> dramobj);
    bool pe_start;
    bool pe_done;
    u32 pe_mode;
    u32 ifm_width;
    u32 ifm_height;
    u32 ifm_num;
    u32 ifm_start_addr_h[2];
    u32 ifm_start_addr_l[2];
    u32 ifm_size;
    u32 ifm_offset[2];
    u32 ofm_width;
    u32 ofm_height;
    u32 ofm_num;
    u32 ofm_start_addr_h;
    u32 ofm_start_addr_l;
    u32 ofm_size;
    u32 ofm_offset;
    u32 element_q1;
    u32 element_q2;
    u32 re_mul_num;
    s32 out_shift;
    u32 padding_idc;
    s8 padding_word;
    u32 padding_size;
    u32 pooling_stride;
    void Run();
    ~VectorPath();
private:
    s8 *ifmBuffer[2], *ofmBuffer;
    void element_wise(u32 length);
    void pooling(u64 ofm_addr, u64 ifm_addr);
    void pooling_tile(u32 input_w, u32 input_h, 
                      u32 output_w, u32 output_h,
                      u32 pool_w, u32 pool_h, u32 pooling_type,
                      u32 stride_w, u32 stride_h);
    void reduce_sum(u32 length, s64 *result);
    void arg_max(u32 length, u32 index_base, u32 *max_index, s8 *max_value);
    void post_value(s64 *result, bool is_saturate);
    std::shared_ptr<Dram> DramPtr;
};

#endif
